<?php

declare(strict_types = 1);

use Swoole\Server;
use Initiating\TransactionResources\TxTransaction;
use Communication\TxSocketData;
use Communication\TxDatabase;
use Initiating\Constant;
use Swoole\Server\Task;
use Swoole\Runtime;
use Initiating\Pool\RedisPool;
require_once 'vendor/autoload.php';

require_once 'tool.php';

define('BASE_DIR', dirname(__FILE__) . "/db/" );

define('BASE_PATH',str_replace('\\','/',realpath(dirname(__FILE__).'/')).'/');


class App{
	/**
	 * @var TxTransaction
	 */
	public static $txClient;
	
	/**
	 * @var TxDatabase
	 */
	public static $db;
	
	/**
	 *
	 * @var Server
	 */
	public static $server;
	
	/**
	 * 
	 * @var TxTransaction
	 */
	public static $transation;
	
	public static function init(): void {
	
		static::$db = TxDatabase::getInstance()->getConn('user1');
		
	}
	
	public static function getDbConnection() : TxDatabase
	{
		return static::$db;
	}
	
	
}

App::init();

App::$transation = new TxTransaction(App::$db);

class Spl
{
	/**
	 * 
	 * @var SplStack
	 */
	private $spl;
	
	/**
	 * 
	 * @var self
	 */
	private static $obj;
	
	
	private function __construct()
	{
		$this->spl = new SplStack();
	}
	
	public static function init(): void
	{
		static::$obj = new static();
	}
	
	public static function getInstance(): self
	{
		return static::$obj;
	}
	
	public function push($value)
	{
		 $this->spl->push($value);
	}
	
	public function pop()
	{
		return $this->spl->pop();
	}
}

Spl::init();


App::$server  = new Server('127.0.0.1', 9508, SWOOLE_PROCESS, SWOOLE_TCP);

Runtime::enableCoroutine();

App::$server->set([
	'work_num' => 4,
	'domain' =>  true,
	'task_worker_num' => 1,
	'task_enable_coroutine' => true
]);



App::$server->on('receive', function (Server $server, int $fd, int $reactorId, string $data){
	
	$res = json_decode($data, true);
	
	
	App::$transation->initTxGroup($res['group_id']);
	
	
// 	App::$transation = $obj;
	
// 	App::$transation->setGroupId($res['group_id']);
	
// 	$transation = clone App::$transation;
	
	
	App::$transation->begin();
	
	try {
		
		$res = App::$db->query('update `account` set money=money-50', []);
		
		$id = App::$db->affectedCount();
		
		if (!$id) {
			
			App::$transation->rollback();
			
			$response = serialize(TxSocketData::createResponse(Constant::$tx_complete_fail));
		} else {
			$response = serialize(TxSocketData::createResponse('ok'));
			App::$transation->commit();
		}
		
	} catch (\Exception $e) {
		dump($e->getMessage());
		
		App::$transation->rollback();
		
		$response = serialize(TxSocketData::createResponse(Constant::$tx_complete_fail));
	}
	
	
	$server->send($fd, $response);
	
	
});

App::$server->on('task', function(Server $server, Task $task ){

	dump(Spl::getInstance()->pop());
	
});

App::$server->on('WorkerStart', function (Server $server) {
	
	
	
});

// $process = new Process(function (Process $process){
	
// // 	$process->write($data);
// 	ReceiveMessage::getInstance()->received(App::$transation, 'zblQueue', 0);
// }, false, 2, true);

// App::$server->addProcess($process);

App::$server->on('PipeMessage', function (swoole_server $server, int $src_worker_id,  $message){
	
	
});


App::$server->start();